using System.Collections;
using System.Collections.Generic;
using Commons.Models.Definitions;
using Commons.Preferences;
using Commons.Models.Settings.Dtos;
using Commons.Models.Settings.Dtos.Questions;
using Commons.Commons.Models.Definitions;
using Commons.Models.Locks;
using Commons.Models.TradeValues;
using Commons.Models.Settings.Mappers.Locks;
using Commons.Models.Settings.Mappers.TradeValues;
using System;

namespace Commons.Models.Settings.Parsers
{
	public class GameSettingsParser : BaseSettingsParser<GameConfigDto>
	{
		public GameSettingsParser()
			: base("Resources/game-config")
		{
		}

		public override IEnumerator Parse(ParserContext context, ISettingsModel settingsModel)
		{
            GameConfigDto config = Deserialize();
			yield return null;

			TotalObjects = config.Categories.Count + config.Questions.Count;

			// Parse Categories
            Dictionary<int, QuestionCategoryDefinition> categories = new Dictionary<int, QuestionCategoryDefinition>();

            foreach (QuestionCategoryDefinitionDto catDto in config.Categories)
			{
                QuestionCategoryDefinition cat = new QuestionCategoryDefinition(catDto.Id, catDto.Name);
				categories.Add(cat.Id, cat);
				NumObjects++;
				yield return null;
			}

			// Parse items
            Dictionary<int, QuestionDefinition> questions = new Dictionary<int, QuestionDefinition>();

            foreach (QuestionDefinitionDto qDto in config.Questions)
			{
                int qId = qDto.Id;
                int qCorrectAnswerId = qDto.CorrectAnswerId;
                Lock qLock = new LockMapper().Map(qDto.Lock);
                ITradeValue qReward = new RewardMapper().Map(qDto.Reward);
                List<QuestionCategoryDefinition> qCats = new List<QuestionCategoryDefinition>();
                
                foreach(string catId in qDto.Categories.Split(','))
                {
                    QuestionCategoryDefinition qCat = null;
                    if (categories.TryGetValue(Convert.ToInt32(catId), out qCat))
                        qCats.Add(qCat);
                }

                List<AnswerDefinition> qAns = new List<AnswerDefinition>(qDto.Answers.Count);
                foreach (AnswerDto aDto in qDto.Answers)
                {
                    qAns.Add(new AnswerDefinition(aDto.Id, aDto.Value));
                }

                QuestionDefinition definition = new QuestionDefinition(qId, qCorrectAnswerId, qCats, qAns, qLock, qReward);
				questions.Add(definition.Id, definition);
				NumObjects++;
				yield return null;
			}

			settingsModel.AddSetting(new GameSettings(questions, categories));
		}
	}
}

